#include <linux/init.h>         //包含宏定义得头文件
#include <linux/module.h>       //包含初始化加载模块得头文件
#include <linux/kdev_t.h>       //处理设备号宏定义的头文件
#include <linux/fs.h>           //文件操作集
#include <linux/uaccess.h>      //copy_to_user函数的文件
#include <linux/io.h>           //ioermap等函数的头文件
#include <linux/platform_device.h>       //自动创建设备节点的头文件
// #include <linux/cdevdevice.h>   //杂项设备头文件
/*包含头文件*/
/*************platfrom平台总线模型简单的platform_driver文件的编写***********
*平台总线模型的目的是将驱动代码和硬件资源的描述分隔开从而提高驱动代码的复用性因此分开了
*驱动 总线 设备三个文件来描述，device driver
*（1）设计平台总线模型需要分别注册device与driver，两者通过字符串命名来实现配对
*（2）先定义一个platform_driver结构体变量实现各个结构体成员
*（3）命名一样配对device与driver后完成probe函数的编写，主要重点完成probe函数的编写
*（4）
*（5）
*（6）
* (7)注意点：/sys/devices/platform/可以查看对应得的
***********************************************************************/

/*************platform_driver内容处理************/
int beep_probe(struct platform_device*pdev)
{
    printk("beep_probe\n");
    return 0;
}

int beep_remove(struct platform_device*pdev)
{
    printk("beep_remove byb!\n");
    return 0;
}

const struct platform_device_id beep_idtable={
    .name="123"
};

struct platform_driver beep_driver={   //通过.name名字与device匹配成功后会执行prode函数
    .probe =beep_probe,
    .remove=beep_remove,
    .driver={
        .owner = THIS_MODULE,
        .name="beep_test"
    },
    .id_table = &beep_idtable   //该变量比.driver中的.name优先级要高
};

/*功能实现*/
static int beep_driver_init(void)
{
    int plat_reg=0;
    plat_reg =platform_driver_register(&beep_driver);
    if(plat_reg<0){
        printk("platform_driver_register error!\n");
    }
    printk("platform_driver_register ok!\n");

    return 0;
    //映射地址在init函数内这样加载上驱动就映射完成了
    // vir_gpio5_dr=ioermap();
}

static void beep_driver_exit(void)//退出函数没有返回值
{
    platform_driver_unregister(&beep_driver);
    printk("byb byb !");  
}     


module_init(beep_driver_init);
module_exit(beep_driver_exit); 
/*驱动的出口与入口函数都在此处*/
MODULE_LICENSE("GPL");
/*申明信息*/
	
/*注意在开发板中加载驱动的时候一定要保持板卡的内核和编译的内核是一致的否则会报错
*查看设备节点：ls /dev/hello_cdev
*/


